<?php

namespace app\controller\admin;

use app\service\AuthService;
use support\Request;
use support\Db;
use hg\apidoc\annotation as Apidoc;
use app\support\Response;

/**
 * @Apidoc\Title("系统命令管理")
 * @Apidoc\Group("admin")
 * @Apidoc\Sort("999")
 */
class CommandController
{
    /**
     * 允许执行的命令白名单
     */
    private $allowedCommands = [
        'ls', 'll', 'dir',
        'docker',
        'php',
        'composer',
        'git',
        'npm',
        'systeminfo',
        'df',
        'free',
        'top',
        'ps',
        'mysql'
    ];

    /**
     * @Apidoc\Title("执行系统命令")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/admin/command/execute")
     * @Apidoc\Tag("系统管理")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("command", type="string", require=true, desc="要执行的系统命令")
     * @Apidoc\Returned("data", type="object", desc="返回数据", children={
     *   @Apidoc\Returned("command", type="string", desc="执行的命令"),
     *   @Apidoc\Returned("output", type="array", desc="命令输出结果"),
     *   @Apidoc\Returned("return_code", type="int", desc="命令返回码，0表示成功")
     * })
     * @Apidoc\Desc("执行系统命令，支持：ls, ll, dir, docker, php, composer, git, npm, systeminfo, df, free, top, ps, mysql")
     */
    public function execute(Request $request)
    {
        // 验证超级管理员权限
        /*if (!$request->admin || $request->admin['is_super'] != 1) {
            return Response::error('需要超级管理员权限');
        }*/

        // 获取要执行的命令
        $command = $request->post('command');
        if (empty($command)) {
            return Response::error('命令不能为空');
        }

        // 检查是否是MySQL连接查看命令
        if ($command === 'mysql status') {
            return $this->getMysqlStatus();
        }
        // 检查命令是否在白名单中
        $isAllowed = false;
        foreach ($this->allowedCommands as $allowedCmd) {
            if (strpos($command, $allowedCmd) === 0) {
                $isAllowed = true;
                break;
            }
        }

        if (!$isAllowed) {
            return Response::error('该命令不在允许列表中:' . $command);
        }

        // 执行命令
        $output = [];
        $returnCode = 0;
        exec($command . ' 2>&1', $output, $returnCode);

        // 记录日志
        $this->logCommand($command, $output, $returnCode);

        return Response::success([
            'command' => $command,
            'output' => $output,
            'return_code' => $returnCode
        ]);
    }

    /**
     * 获取MySQL连接状态
     */
    private function getMysqlStatus()
    {
        try {
            // 获取数据库连接配置
            $config = config('database.connections.mysql');
            
            // 获取数据库连接状态
            $status = [
                'connection_info' => [
                    'host' => $config['host'] ?? 'unknown',
                    'port' => $config['port'] ?? 'unknown',
                    'database' => $config['database'] ?? 'unknown',
                    'username' => $config['username'] ?? 'unknown',
                    'charset' => $config['charset'] ?? 'unknown',
                    'prefix' => $config['prefix'] ?? '',
                ],
                'server_info' => null,
                'server_version' => null,
                'client_info' => null,
                'client_version' => null,
                'protocol_version' => null,
                'connection_status' => null,
                'connection_stats' => null
            ];

            // 获取PDO连接信息
            $pdo = Db::connection('mysql')->getPdo();
            $status['server_info'] = $pdo->getAttribute(\PDO::ATTR_SERVER_INFO);
            $status['server_version'] = $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION);
            $status['client_version'] = $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION);
            $status['connection_status'] = $pdo->getAttribute(\PDO::ATTR_CONNECTION_STATUS);

            // 获取更多连接信息
            $result = Db::select('SHOW VARIABLES LIKE "version%"');
            foreach ($result as $row) {
                $status['mysql_variables'][$row->Variable_name] = $row->Value;
            }

            // 获取连接统计信息
            $processlist = Db::select('SHOW PROCESSLIST');
            $status['current_connections'] = count($processlist);

            // 记录日志
            $this->logCommand('mysql status', [$status], 0);

            return Response::success($status);
        } catch (\Exception $e) {
            return Response::error('获取MySQL状态失败：' . $e->getMessage());
        }
    }

    /**
     * 记录命令执行日志
     */
    private function logCommand($command, $output, $returnCode)
    {
        $logData = [
            'timestamp' => date('Y-m-d H:i:s'),
            'command' => $command,
            'output' => $output,
            'return_code' => $returnCode,
            'ip' => request()->getRealIp(),
            'admin_id' => request()->admin['id'] ?? 0,
            'admin_name' => request()->admin['username'] ?? 'unknown'
        ];

        $logFile = runtime_path() . '/logs/admin_command.log';
        file_put_contents(
            $logFile,
            json_encode($logData, JSON_UNESCAPED_UNICODE) . "\n",
            FILE_APPEND
        );
    }
} 